package system.struct;

import java.math.*;

import system.util.Util;

/**
 * This implementation is used to describe <tt>SearchEntry</tt> fetched out from
 * <tt>Loader</tt> by <tt>Fetcher</tt>
 * <p>
 * In implementation of <tt>Fetcher</tt>, <tt>SearchEntry</tt> is transformed
 * from <tt>AggEntry</tt>
 * 
 * @author Jack
 * 
 */
public class SearchEntry implements Comparable<SearchEntry> {
	private static double MIN_DISTANCE = 0.0001;
	LogEntry le;
	/** index of matched <i>Probase Instance</i> */
	int iIndex;
	/** <tt>String</tt> with all matched <i>Probase Concept</i> kicked out */
	String keywords;
	/** distance between keyword and user-input query */
	double distance;

	/**
	 * Constructs a <tt>SearchEntry</tt> using given <tt>LogEntry</tt>,
	 * <i>keyword</i> and <i>Instance Index</i>
	 * 
	 * @param le
	 *            <tt>LogEntry</tt> this instance directs to
	 * @param keywords
	 *            <tt>String</tt> with all matched <i>Probase Concept</i> kicked
	 *            out
	 * @param iIndex
	 *            index of matched <i>Probase Instance</i>
	 */
	public SearchEntry(LogEntry le, String keywords, int iIndex) {
		this.le = le;
		this.keywords = keywords;
		this.iIndex = iIndex;
		this.distance = MIN_DISTANCE;
	}

	/**
	 * Set distance of this <tt>SearchEntry</tt>
	 * 
	 * @param distance
	 */
	public void setDistance(int distance) {
		this.distance = Math.max(distance, MIN_DISTANCE);
	}

	/**
	 * Returns the ranking score of this <tt>SearchEntry</tt>
	 * 
	 * @return ranking score of this <tt>SearchEntry</tt>
	 */
	public double score() {
		return le.quality / distance;
	}

	/**
	 * Returns <i>Query Index</i> of this <tt>SearchEntry</tt>
	 * 
	 * @return <i>Query Index</i> of this <tt>SearchEntry</tt>
	 */
	public int qIndex() {
		return le.qIndex;
	}

	/**
	 * Returns <i>Instance Index</i> of this <tt>SearchEntry</tt>
	 * 
	 * @return <i>Instance Index</i> of this <tt>SearchEntry</tt>
	 */
	public int iIndex() {
		return iIndex;
	}

	/**
	 * Returns <i>keywords</i> of this <tt>SearchEntry</tt>
	 * 
	 * @return <i>keywords</i> of this <tt>SearchEntry</tt>
	 */
	public String keywords() {
		return keywords;
	}

	/**
	 * Cut <i>keywords</i> using given <tt>String</tt>
	 * 
	 * @param str
	 *            given <tt>String</tt>
	 */
	public void cutKeywords(String str) {
		keywords = Util.replaceAll(keywords, str);
	}

	@Override
	public int compareTo(SearchEntry o) {
		double score = this.score() - o.score();
		if (score == 0)
			return this.le.qIndex - o.le.qIndex;
		else
			return (score < 0) ? -1 : 1;
	}

	/**
	 * Returns the information of this <tt>SearchEntry</tt>
	 * 
	 * @return the information of this <tt>SearchEntry</tt>
	 */
	public String info() {
		return score() + "\t" + le.query;
	}

	public String toString() {
		return "le: " + distance + "\t" + keywords + "\t" + le.toString();
	}

}
